﻿#include "TcpServer.h"

#include <QBuffer>
#include <QDateTime>
#include <QImage>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QMetaType>
#include <QTimer>

#include "MainWindow.h"

TcpServer::TcpServer(QObject *parent) :
    QObject(parent),
    m_sendMsgLenCnt(0),
    m_revMsgLenCnt(0),
    m_server(new QTcpServer(this))
{
    connect(m_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}

void TcpServer::cleanup()
{
    stopListen();
    delete m_server;
    m_server = nullptr;
}

bool TcpServer::listen(const QHostAddress &ip, int port)
{
    if (m_server->listen(ip, port)) {
        qDebug() << "IOP TcpServer: listening...";
        emit sigSystemLog("UDP开始监听" + MainWindow::getIpAndPortStr(ip, port) + "，等待客户端接入");

        return true;
    } else {
        qInfo() << "IOP TcpServer: listen failed";
        emit sigSystemLog("UDP服务器监听失败！");

        return false;
    }
}

bool TcpServer::stopListen()
{
    if (m_server->isListening()) {
        delete m_server;
        m_server = nullptr;

        m_server = new QTcpServer(this);
        connect(m_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));

        qDebug() << "IOP TcpServer: close listen port";
    } else {
        qInfo() << "IOP TcpServer: port is not listened";
    }

    m_clientObjList.clear();
    emit sigClientUpdate();
    return !m_server->isListening();
}

void TcpServer::deleteClient(const QString &clientStr)
{
    if (m_clientObjList.keys().contains(clientStr)) {
        auto client = m_clientObjList.value(clientStr);
        client->disconnectFromHost();   //主动和客户端断开连接
        client->close();
        client = nullptr;

        emit sigSystemLog("TCP客户端" + clientStr + "断开了本地服务器");
        m_clientObjList.remove(clientStr);
    }
}

void TcpServer::sendMsgToClient(const QString &clientStr, const QByteArray &msg)
{
    if (m_clientObjList.keys().contains(clientStr)) {
        m_clientObjList.value(clientStr)->write(msg.data(), msg.length());

        m_sendMsgLenCnt += msg.size();
        emit sigCNTUpdate(m_sendMsgLenCnt, m_revMsgLenCnt);
    }
}

void TcpServer::onNewConnection()
{
    auto client = m_server->nextPendingConnection();
    auto tmpName = MainWindow::getIpAndPortStr(client->peerAddress(), client->peerPort());

    if (m_clientObjList.size() < MAX_TCP_CLIENT) {
        m_clientObjList.insert(tmpName, client);

        connect(client, SIGNAL(disconnected()), SLOT(onDisconnected()));
        connect(client, &QTcpSocket::readyRead, this, &TcpServer::onMessageCTRL);

        qDebug() << "IOP TcpServer: New connection accepted!! client num:" << m_clientObjList.size();
        emit sigSystemLog("TCP客户端" + tmpName + "连接到本机");
        emit sigClientUpdate();
    } else {
        qInfo() << "IOP TcpServer: MAX connect, error!";
        client->disconnectFromHost();
        client->deleteLater();
    }
}

void TcpServer::onDisconnected()
{
    QTcpSocket *client = static_cast<QTcpSocket *>(sender());
    deleteClient(MainWindow::getIpAndPortStr(client->peerAddress(), client->peerPort()));

    qDebug() << "IOP TcpServer: Client disconnected!! client num:" << m_clientObjList.size();
    emit sigClientUpdate();
}

void TcpServer::onMessageCTRL()
{
    QTcpSocket *client = static_cast<QTcpSocket *>(sender());
    QByteArray body = client->readAll();

    m_revMsgLenCnt += body.size();
    emit sigReadMsg(MainWindow::getIpAndPortStr(client->peerAddress(), client->peerPort()), body);
    emit sigCNTUpdate(m_sendMsgLenCnt, m_revMsgLenCnt);
    qInfo() << "IOP TcpServer: Get MSG:" << client->peerName() << body;
}
